<template>
    <div v-loading="pageLoading">
        <!-- 返回 -->
        <el-card shadow="never" class="!border-none">
            <el-page-header
                :content="'畅阅模式' + (formData.id ? '编辑' : '新增')"
                @back="emits('listen', 'lists')"
            />
        </el-card>

        <!-- 表单 -->
        <el-form ref="formRef" :rules="rules" :model="formData" label-width="90px">
            <el-card shadow="never" class="!border-none mt-4">
                <div class="text-xl font-medium mb-6">基础配置</div>
                <el-form-item label="模式图标" prop="icon">
                    <div class="w-[400px]">
                        <material-picker
                            v-model="formData.icon"
                            :limit="1"
                        />
                    </div>
                </el-form-item>
                <el-form-item label="模式名称" prop="name">
                    <div class="w-[400px]">
                        <el-input
                            v-model="formData.name"
                            placeholder="请输入模式名称"
                            maxlength="100"
                        />
                    </div>
                </el-form-item>
                <el-form-item label="模式描述" prop="intro">
                    <div class="w-[400px]">
                        <el-input
                            v-model="formData.intro"
                            placeholder="请输入模式描述"
                            maxlength="100"
                        />
                    </div>
                </el-form-item>
                <el-form-item label="排序" prop="sort" required>
                    <el-input-number v-model="formData.sort" :min="0" :max="999999" />
                </el-form-item>
                <el-form-item label="状态" prop="is_disable">
                    <div class="w-[400px]">
                        <el-radio-group v-model="formData.is_disable">
                            <el-radio :value="0">正常</el-radio>
                            <el-radio :value="1">停用</el-radio>
                        </el-radio-group>
                    </div>
                </el-form-item>
            </el-card>

            <!-- 对话 -->
            <el-card shadow="never" class="!border-none mt-4">
                <div class="text-xl font-medium mb-6">【对话】提示词</div>
                <div class="max-w-[700px]">
                    <models-setting
                        v-model="formData.dialogue_conf.model"
                        :params="formData.dialogue_conf.params"
                        @change="(data: any) => {
                            formData.dialogue_conf.params = data.params
                        }"
                    />
                    <el-form-item label="提示词">
                        <template #label>
                            <span class="mr-[4px] mt-[2px]">提示词</span>
                            <el-tooltip
                                class="box-item"
                                effect="dark"
                                :content="promptTipsA"
                                placement="right"
                            >
                                <icon :size="16" name="el-icon-QuestionFilled" />
                            </el-tooltip>
                        </template>
                        <el-input
                            type="textarea"
                            :rows="15"
                            v-model.trim="formData.dialogue_conf.prompt"
                            show-word-limit
                        />
                    </el-form-item>
                </div>
            </el-card>

            <!-- 总结 -->
            <el-card shadow="never" class="!border-none mt-4">
                <div class="flex items-center gap-x-4 text-xl font-medium mb-6">
                    【总结】提示词
                    <el-button :icon="Plus" @click="agentCreate" />
                </div>
                <div class="flex">
                    <div class="w-[400px] pr-8 border-r border-dashed">
                        <Draggable
                            v-model="formData.abstract_conf"
                            :item-key="'selected'"
                            animation="300"
                            handle=".drag-move"
                        >
                            <template #item="{ element, index }">
                                <div
                                    class="flex items-center py-2 px-4 border rounded-md mb-4
                                           hover:bg-primary-light-9 cursor-pointer"
                                    :class="{ 'border-primary': index === agentIndex }"
                                    @click="agentIndex = index"
                                >
                                    <div class="flex-1">
                                        <div class="flex items-center gap-x-3">
                                            <h3 class="text-xl font-bold">Agent-{{ index + 1 }}</h3>
                                            <span class="text-xs text-tx-placeholder">{{ element.name }}</span>
                                        </div>
                                        <div class="text-xs text-tx-placeholder mt-1">
                                            {{ element.model || '-' }}
                                        </div>
                                    </div>
                                    <div class="flex items-center gap-x-3">
                                        <icon
                                            class="hover:text-error"
                                            name="el-icon-Delete"
                                            size="18"
                                            @click.stop="agentDelete(index)"
                                        />
                                        <div class="flex drag-move cursor-move">
                                            <icon name="el-icon-Rank" size="18" />
                                        </div>
                                    </div>
                                </div>
                            </template>
                        </Draggable>
                    </div>
                    <div class="flex-1 max-w-[700px] ml-8 p-3 border rounded-md">
                        <el-form-item label="步骤名" required>
                            <el-input v-model.trim="formData.abstract_conf[agentIndex].name" />
                        </el-form-item>
                        <models-setting
                            v-if="formData.abstract_conf"
                            v-model="formData.abstract_conf[agentIndex].model"
                            :params="formData.abstract_conf[agentIndex].params"
                            @change="(data: any) => {
                                formData.abstract_conf[agentIndex].params = data.params
                            }"
                        />
                        <el-form-item label="提示词">
                            <template #label>
                                <span class="mr-[4px] mt-[2px]">提示词</span>
                                <el-tooltip
                                    class="box-item"
                                    effect="dark"
                                    :content="promptTipsB"
                                    placement="right"
                                >
                                    <icon :size="16" name="el-icon-QuestionFilled" />
                                </el-tooltip>
                            </template>
                            <el-input
                                type="textarea"
                                :rows="15"
                                v-model.trim="formData.abstract_conf[agentIndex].prompt"
                                show-word-limit
                            />
                        </el-form-item>
                    </div>
                </div>
            </el-card>

            <!-- 按钮 -->
            <el-card shadow="never" class="!border-none mt-4 text-center">
                <el-button @click="emits('listen', '', 'lists', 0)">取消</el-button>
                <el-button
                    v-perms="['apply:docs:prompt:add', 'apply:docs:prompt:edit']"
                    :loading="loading"
                    type="primary"
                    @click="handleSubmit"
                >保存</el-button>
            </el-card>
        </el-form>
    </div>
</template>

<script setup lang="ts">
import { Plus } from '@element-plus/icons-vue'
import Draggable from 'vuedraggable'
import feedback from '@/utils/feedback'
import docsPromptApi from '@/api/apply/docs/prompt'

const emits = defineEmits(['listen'])
const props = defineProps({
    id: {
        type: Number,
        default: 0
    }
})

// 页面加载
const pageLoading = ref<boolean>(false)

// 表单数据
const loading = ref<boolean>(false)
const formRef = ref()
const formData = ref<any>({
    id: '',               // ID
    code: '',             // 编号
    icon: '',             // 图标
    name: '',             // 名称
    intro: '',            // 简介
    is_disable: 0,        // 是否禁用:[0=否, 1=是]
    abstract_conf: [{}],  // 总结模型参数
    dialogue_conf: {}     // 对话模型参数
})

// 表单验证
const rules = {
    'icon': [
        { required: true, message: '请上传模式图标', trigger: 'blur' }
    ],
    'name': [
        { required: true, message: '模式名称不能为空', trigger: 'blur' }
    ],
    'intro': [
        { required: true, message: '模式描述不能为空', trigger: 'blur' }
    ],
    'is_disable': [
        { required: true, message: '请正确选择状态开关', trigger: 'blur' }
    ]
}

// 当前Agent
const agentIndex = ref<number>(0)
const promptTipsA: string = '可用变量: {{input}}表示文档内容，{{abstract}}表示总结的内容。'
const promptTipsB: string = '可用变量: {{input}}表示文档内容，{{output-1}}表示指定步奏的结果作为输入。'

/**
 * Agent新增
 *
 * @return void
 * @author zero
 */
const agentCreate = (): void => {
    formData.value.abstract_conf.push({
        name: '',
        model: '',
        params: {},
        prompt: ''
    })

    agentIndex.value = formData.value.abstract_conf.length - 1
}

/**
 * Agent删除
 *
 * @param {number} index
 * @return void
 * @author zero
 */
const agentDelete = (index: number): void => {
    if (formData.value.abstract_conf.length <= 1) {
        feedback.msgError('至少需要保留1个Agent');
        return
    }
    feedback.confirm(`确定要删除 'Agent-${index+1}' 吗?`)
        .then(() => {
            formData.value.abstract_conf.splice(index, 1)
            if (index === agentIndex.value) {
                agentIndex.value = 0
            }
        }).catch(() => {})
}

/**
 * 提交表单
 *
 * @return Promise<void>
 * @author zero
 */
const handleSubmit = async (): Promise<void> => {
    if (!formData.value.dialogue_conf.model) {
        feedback.msgError(`【对话配置】请选择AI模型`);
        return
    }

    if (!formData.value.dialogue_conf.prompt) {
        feedback.msgError(`【对话配置】请填写提示词`);
        return
    }

    if (formData.value.abstract_conf.length <= 0) {
         feedback.msgError('【总结Agent】至少需要保留1个')
         return
    }

    for (const [index, item] of formData.value.abstract_conf.entries()) {
        if (!item.name) {
            feedback.msgError(`Agent-${index+1} 请填写步骤名称`);
            return
        }
        if (!item.model) {
            feedback.msgError(`Agent-${index+1} 请选择AI模型`);
            return
        }
        if (!item.prompt) {
            feedback.msgError(`Agent-${index+1} 请填写提示词`);
            return
        }
    }

    // 发起提交请求
    await formRef.value?.validate().then(async () => {
        loading.value = true
        if (props.id) {
            await docsPromptApi.edit(formData.value)
                .finally(() => {
                    loading.value = false
                })
        } else {
            await docsPromptApi.add(formData.value)
                .finally(() => {
                    loading.value = false
                })
        }

        feedback.msgSuccess('操作成功')
        emits('listen', 'lists')
    }).catch(() => {})
}

watch(
    () => props.id,
    async () => {
        if (props.id) {
            pageLoading.value = true
            formData.value = await docsPromptApi.detail(props.id)
            pageLoading.value = false
        }
    },
    { immediate: true }
)
</script>
